/***********************************************************************************
 * 文 件 名   : FrameDataParser.c
 * 负 责 人   : jiangfeng.zhang
 * 创建日期   : 2021年7月8日
 * 文件描述   : 数据帧解析源文件
 * 版权说明   : Copyright (c) 2008-2021   Personal. All rights reserved.
 * 其    他   :
 * 修改日志   :
***********************************************************************************/
#include "FrameDataParser.h"
#include "stdio.h"
#include "string.h"

/* [add by jiangfeng.zhang, 2021-07-08] :由于当前逻辑平台没有malloc,此处直接定义全局静态区*/
ST_FRAME   g_stFrame;

#if 0
/***********************************************************************
 * 函数名称: CreateFrameBufferForMalloc
 * 功能描述: 针对有malloc机制,创建FramBuffer
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
ST_FRAME *CreateFrameBufferFun0(int bufSize)
{
    int i = 0;
    ST_FRAME *pFrame = (ST_FRAME *)malloc(sizeof(ST_FRAME));
    pFrame->buffer = (unsigned char *)malloc(bufSize);
    pFrame->recvFlag = RecvNothing;
    pFrame->escape = EscapeDisEnable;
    pFrame->bufSize = bufSize;
    memset(pFrame->buffer, 0, bufSize);
    return pFrame;
}
#endif
/***********************************************************************
 * 函数名称: CreateFrameBufferForMalloc
 * 功能描述: 针对无Malloc的数组机制
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
int CreateFrameBufferFun1(ST_FRAME *pFrame, int bufSize)
{
    int i = 0;
    if (pFrame == NULL || bufSize <= 0 ||bufSize>MAX_BUFFER_LEN)
    {
        return FRAME_NULL;
    }
    pFrame->recvFlag = RecvNothing;
    pFrame->escape = EscapeDisEnable;
    pFrame->bufSize = bufSize;
    memset(pFrame->buffer, 0, bufSize);
    return FRAME_PARSER_SUCCESS;
}

/***********************************************************************
 * 函数名称: FrameDataPack
 * 功能描述: 打包数据帧
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 			注意：outputBuf长度一定要足够,否则会溢出
 ***********************************************************************/
int FrameDataPack(unsigned char *inputBuf, int iutputBufLen, unsigned char *outputBuf)
{
    int index = 0;
    int i = 0;
    /*填字包头C0*/
    outputBuf[index++] = 0xC0;
    outputBuf[index++] = 0x0;
    outputBuf[index++] = 0x02;
    outputBuf[index++] = 0x01;  //channeltype
    outputBuf[index++] = 0x28;  //msgnum

    for (i = 0; i < iutputBufLen; i++)
    {
        switch (inputBuf[i])
        {
            case 0xC0:
                outputBuf[index++] = 0xDB;
                outputBuf[index++] = 0xDC;
                break;
            case 0xDB:
                outputBuf[index++] = 0xDB;
                outputBuf[index++] = 0xDD;
                break;
            default:
                outputBuf[index++] = inputBuf[i];
                break;
        }
    }
    /*填字包尾C0*/
    outputBuf[index++] = 0x00;
    outputBuf[index++] = 0xC0;
    return index;
}


/***********************************************************************
 * 函数名称: FrameDataUnpack
 * 功能描述: 解析单字节数据流,输出一个完整的数据帧
 * 输入参数: 
 			data:单字节流数据
 			frame:此处作为输出参数
 * 输出参数:
 * 返 回 值:
 			 1:数据帧解析成功
 			 0:数据帧解析失败
 *  其   它:
           包头包尾单字节,带转义功能
           0xc0 xx xx 0xc0
 ***********************************************************************/
int FrameDataUnpack(ST_FRAME *frame, unsigned char data)
{
    int ret = FRAME_PARSER_ERROR;
    switch (frame->recvFlag)
    {
        case RecvNothing:
            if (0xC0 == data)
        	{
	            frame->recvFlag = RecvHeader; 
				//如果不想把包头数据整进去,此处可以去掉
			    frame->buffer[frame->len++] = 0xC0;
        	}
            break;
        case RecvHeader:
            if (0xC0 == data)
            {
                if (frame->len < 2)
                {
                    frame->recvFlag = RecvHeader;
                }
                else
                {
                	/* [add by jiangfeng.zhang, 2021-07-08] :整帧数据接收完成,直接返回*/
				   //如果不想把包尾数据整进去,此处可以去掉
					frame->buffer[frame->len++] = 0xC0;
					return FRAME_PARSER_SUCCESS;
                }
            }
            else
            {
                if (frame->len >= frame->bufSize)
                {
                    //溢出
                    ResetFrame(frame);
                    ret = FRAME_PARSER_ERROR;
                    break;
                }
                //在线即时转义
                if (frame->escape)
                {
                    if (0xDC == data)
                    {
                        frame->buffer[frame->len++] = 0xC0;
                    }
                    else if (0xDD == data)
                    {
                        frame->buffer[frame->len++] = 0xDB;
                    }
                    else
                    {
                        //非法转义字符，忽略转义
                        frame->buffer[frame->len++] = data;
                    }
                    frame->escape = EscapeDisEnable;
                }
                else
                {
                    if (0xDB == data)
                    {
                        frame->escape = EscapeEnable;
                    }
                    else
                    {
                        frame->buffer[frame->len++] = data;
                    }
                }
            }
            break;
        default:
            ResetFrame(frame);
            break;
    }
    return ret;
}


/***********************************************************************
 * 函数名称: FrameDataUnpackSingleWithoutEsc
 * 功能描述: 解析单字节数据流,输出一个完整的数据帧
 * 输入参数: 
 			data:单字节流数据
 			frame:此处作为输出参数
 * 输出参数:
 * 返 回 值:
 			 1:数据帧解析成功
 			 0:数据帧解析失败
 *  其   它:
 			 包头包尾单字节+不带转译功能：需保证数据段不含0xc0
 			 0xc0 .. 0xc0
 ***********************************************************************/
int FrameDataUnpackSingleWithoutEsc(ST_FRAME *frame, unsigned char data)
{
    int ret = FRAME_PARSER_ERROR;
    switch (frame->recvFlag)
    {
        case RecvNothing:
            if (0xC0 == data)
        	{
                frame->recvFlag = RecvHeader; 
			    frame->buffer[frame->len++] = 0xC0;
        	}
            break;
        case RecvHeader:
			//连续两个0xc0,认为不合理,继续等待数据。
            if (0xC0 == data)
            {
                if (frame->len < 2)
                {
                    frame->recvFlag = RecvHeader;
                }
                else
                {
                	/* [add by jiangfeng.zhang, 2021-07-08] :整帧数据接收完成,直接返回*/
					frame->buffer[frame->len++] = 0xC0;
					return FRAME_PARSER_SUCCESS;
                }
            }
            else
            {
                if (frame->len >= frame->bufSize)
                {
                    //溢出
                    ResetFrame(frame);
                    ret = FRAME_PARSER_ERROR;
                    break;
                }
                else
                {
                    frame->buffer[frame->len++] = data;
                }
            }
            break;
        default:
            ResetFrame(frame);
            break;
    }
    return ret;
}


/***********************************************************************
 * 函数名称: FrameDataUnpackDoubleWithoutEsc
 * 功能描述: 解析单字节数据流,输出一个完整的数据帧
 * 输入参数: 
 			data:单字节流数据
 			frame:此处作为输出参数
 * 输出参数:
 * 返 回 值:
 			 1:数据帧解析成功
 			 0:数据帧解析失败
 *  其   它:
 			 包头包尾双字节+不带转译功能,不考虑中间数据字段出现连续0xeb 0x90
 			 0xeb 0x90 ... 0xed 0x03
 ***********************************************************************/
int FrameDataUnpackDoubleWithoutEsc(ST_FRAME *frame, unsigned char data)
{
    int ret = FRAME_PARSER_ERROR;
    switch (frame->recvFlag)
    {
        case RecvNothing:
            if (0xeb == data)
        	{
			    frame->buffer[frame->len++] = data;
				frame->recvFlag = RecvFirstHeader; 
        	}
            break;
		case RecvFirstHeader:
			//检测到0xeb前提下,紧接着检测到0x90,则认为检测到了包头。
			if(0x90==data)
			{
				frame->buffer[frame->len++] = data;
				frame->recvFlag = RecvHeader; 
			}
			//已经检测到0xeb,但是下一个数据检测到的不是0x90,认为数据有问题,重新找包头包尾。
			else
			{
				 ResetFrame(frame);
			}
            break;
        case RecvHeader:
		    //0xed有可能只是数据段，有可能是包尾
            if (0xed == data)
            {
            	frame->recvFlag = RecvSubTail; 
			    frame->buffer[frame->len++] = data;
            }
            else
            {
                if (frame->len >= frame->bufSize)
                {
                    //溢出
                    ResetFrame(frame);
                    ret = FRAME_PARSER_ERROR;
                    break;
                }
                else
                {
                    frame->buffer[frame->len++] = data;
                }
            }
            break;
		case RecvSubTail:	
			//检测到0xed的前提下,仅接着看这次数据是否是帧尾的最后一个字节0x03
			if (0x03 == data)
			{
				/* [add by jiangfeng.zhang, 2021-07-08] :整帧数据接收完成,直接返回*/
				frame->buffer[frame->len++] = data;
				return FRAME_PARSER_SUCCESS;
			}
			if(0xed !=data)
			{
				frame->recvFlag = RecvHeader;
				frame->buffer[frame->len++] = data;
			}
			//else分支主要考虑此种情况：eb 90 11 22 33 44 55 66 77 ed ed 03
			else
			{
				frame->buffer[frame->len++] = data;
			}
			break;
        default:
            ResetFrame(frame);
            break;
    }
    return ret;
}



/***********************************************************************
 * 函数名称: ResetFrame
 * 功能描述: 复位Frame内部各个标志
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
void ResetFrame(ST_FRAME *frame)
{
    frame->recvFlag = RecvNothing;
    frame->len = 0;
    frame->escape = EscapeDisEnable;
}
/***********************************************************************
 * 函数名称: CopyFrameData
 * 功能描述: 从frame中获取数据到buff拷贝数据到Frame
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
int CopyFrameData(ST_FRAME *frame, unsigned char *outbuf)
{
    memcpy(outbuf, frame->buffer, frame->len);
    return frame->len;
}

#if 0
/***********************************************************************
 * 函数名称: CloseFrameF0
 * 功能描述: 对于Malloc方式申请的内存,将内存进行释放
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
void CloseFrameFun0(ST_FRAME *frame)
{
    if (FRAME_NULL == frame)
    {
        return;
    }
    if (frame->buffer)
    {
        free(frame->buffer);
        frame->buffer = FRAME_NULL;
    }
    free(frame);
}
#endif
/***********************************************************************
 * 函数名称: CloseFrameF1
 * 功能描述: 对于数组方式的内存,不做任何操作
 * 输入参数:
 * 输出参数:
 * 返 回 值:
 *  其   它:
 ***********************************************************************/
void CloseFrameFun1(ST_FRAME *frame)
{

}

